﻿using System;
using System.Collections.Specialized;
using System.Collections.Generic;

using System.Text;

using CF.Data;
using System.Xml;
using System.Xml.Linq;
using System.Reflection;
using System.IO;
using Kwan.Data;
using System.Data.SQLite;

namespace CF.Service
{
    public class CreateFiles
    {
        public string ProjectName;
        public string TableName;
        public string ModelExt;
        public string ModelExtCS;
        public string ModelExtDesigner;
        public string ModelExtJS;
        public bool isClass;

        string DataPath = string.Empty;
        string QueryPath = string.Empty;
        string ExtPath = string.Empty;

        public void DoBuild(IList<TColumn> list)
        {
            string ProjectPath = string.Format("Files\\{0}\\", ProjectName);
            ExtPath = string.Format(ProjectPath + "Ext\\{0}\\", TableName);
            DataPath = string.Format(ProjectPath + "{0}.Data\\", ProjectName);
            QueryPath = ProjectPath + "query\\";

            FileHelper.CreateFolder(ProjectPath);
            FileHelper.CreateFolder(DataPath);
            FileHelper.CreateFolder(QueryPath);

            BuildEntity(list);
            BuildQuery(list);
            if (!isClass)
            {
                BuildExt(list);
                FileHelper.CreateFolder(ExtPath);
            }
        }

        #region 创建功能XML
        public void CreateXML()
        {
            string solutionPath = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
            if (solutionPath[solutionPath.Length - 1] != '\\') solutionPath = solutionPath + "\\";
            XElement document = XElement.Load(solutionPath + "DashboardSchema.xml");
            XDocument xe = document.LastNode.Document;
            XElement item = new XElement("item");
            item.SetAttributeValue("id", "2342");
            xe.Add(item);
            document.Add(xe);
            XmlWriter xw = null;
            xw.WriteElementString(solutionPath, item.ToString());
            document.WriteTo(xw);
            //if (document.LastNode.CreateReader() != null) { }
            //document.Descendants("group")
        }
        #endregion

        #region 创建数据库
        public void CreatNewSQLite(string projectName)
        {
            string path = FileHelper.SolutionPath() + "App_Data\\";
            SQLiteConnection.CreateFile(path + projectName + ".db");
            string dbpath = @"Data Source=|DataDirectory|\" + projectName + ".db;Pooling=true;FailIfMissing=false;";
            DBContext.SetConnectionDriver<SqliteDriver>(ConnectionType.Context2);
            DBContext.SetConnectionString(ConnectionType.Context2, dbpath);
        }
        public void CreateTables(IList<TColumn> listTableName)
        {
            using (IConnectinContext cc = DBContext.Context2)
            {
                foreach (TColumn t in listTableName)
                {
                    Command cmd = new Command(MakeTableScript(t.ProjectName,t.TableName));
                    cc.ExecuteNonQuery(cmd);
                }
            }
        }
        public void CreateTable(string ProjectName, string TableName)
        {
            using (IConnectinContext cc = DBContext.Context2)
            {
                Command cmd = new Command(MakeTableScript(ProjectName, TableName));
                cc.ExecuteNonQuery(cmd);
            }
        }
        public string MakeTableScript(string ProjectName, string TableName)
        {
            IList<TColumn> list = (TColumn.projectName == ProjectName & TColumn.tableName == TableName).List<TColumn>(new Region(), "NameEN ASC");
            StringBuilder sb = new StringBuilder();
            //sb.Append("DROP TABLE " + ProjectName + "_" + TableName + ";\r\n");
            sb.Append("CREATE TABLE " + ProjectName + "_" + TableName + " (\r\n");
            sb.Append(" EntityID INTEGER PRIMARY KEY autoincrement");
            foreach (TColumn t in list)
            {
                sb.Append(",\r\n");
                string tType = t.Type == "string" && !string.IsNullOrEmpty(t.Lenth) ? "nvarchar(" + t.Lenth + ")" : Cmds.sqliteType[t.Type];
                sb.Append(t.NameEN + " " + tType);
            }
            sb.Append(");\r\n");
            return sb.ToString();
        }
        #endregion

        public void InitModel(bool hadClass)
        {
            string str = hadClass ? "_Class" : "";
            ModelExt = FileHelper.ReadFile("ModelExt" + str + ".htm");
            ModelExtCS = FileHelper.ReadFile("ModelExtCS" + str + ".htm");
            ModelExtDesigner = FileHelper.ReadFile("ModelExtDesigner" + str + ".htm");
            ModelExtJS = FileHelper.ReadFile("ModelExtJS" + str + ".htm");
        }

        #region 处理Entity
        public string BuildEntity(IList<TColumn> list)
        {
            try
            {
                string path = DataPath;
                StringBuilder sbDefine = new StringBuilder();
                StringBuilder sbGetset = new StringBuilder();
                //llano
                //string ModelEntity = FileHelper.ReadFile("ModelEntity.htm");
                //kwan
                string ModelEntity = FileHelper.ReadFile("ModelEntity_Kwan.htm");

                for (int i = 0; i < list.Count; i++)
                {
                    TColumn c = list[i];
                    string tips = string.IsNullOrEmpty(c.Memo) ? c.Memo : "//" + c.Memo;
                    //llano
                    //string strDefine = string.IsNullOrEmpty(c.Lenth) ? Cmds.publicColumn : Cmds.ColumnLength + Cmds.publicColumn;
                    //sbDefine.Append(string.Format(Cmds.privateColumn, c.NameEN, c.Type, tips));
                    //Kwan
                    //string strDefine = Cmds.publicColumn;
                    //sbDefine.Append(string.Format(Cmds.privateColumn, c.NameEN, c.Type == "int" ? "long" : c.Type, tips));
                    //sbGetset.Append(strDefine.Replace("ColumnLength", "nvarchar(" + c.Lenth + ")").Replace("ColumnName", c.NameEN).Replace("ColumnType", c.Type == "int" ? "long" : c.Type));
                    string s = "\r\n\t\t[Column]\r\n\t\t{0} {1}";
                    sbGetset.AppendFormat(s, c.Type, c.NameEN);
                    sbGetset.Append(" { get; set; }");
                    sbGetset.Append(tips);
                }
                ModelEntity = ModelEntity.Replace("ProjectName", ProjectName);
                ModelEntity = ModelEntity.Replace("TableName", TableName);
                ModelEntity = ModelEntity.Replace("ColumnName", sbDefine.ToString() + "\r\n" + sbGetset.ToString());
                FileHelper.WriteFile(ModelEntity, path + "T" + TableName + ".cs");
                return "OK";
            }
            catch (Exception e)
            {
                return e.Message.ToString();
            }
        }
        #endregion

        #region 处理Query
        public string BuildQuery(IList<TColumn> list)
        {
            try
            {
                string path = QueryPath;
                StringBuilder sb = new StringBuilder();
                StringBuilder sbGetset = new StringBuilder();
                string ModelQuery = FileHelper.ReadFile("ModelQuery.htm");

                if (list.Count == 0) return "OK";

                NameValueCollection ps = new NameValueCollection();
                ps.Set("DateTime", "DateTime.Parse(ps[propName])");
                ps.Set("double", "double.Parse(ps[propName])");
                ps.Set("string", "ps[propName]");
                ps.Set("int", "int.Parse(ps[propName])");
                ps.Set("bool", "bool.Parse(ps[propName])");

                foreach (TColumn c in list)
                {
                    string columnName = c.NameEN.Substring(0, 1).ToLower() + c.NameEN.Substring(1, (c.NameEN.Length - 1));
                    sb.Append(Cmds.strQuery.Replace("TableName", TableName).Replace("ColumnName", columnName).Replace("ColumnFormat", ps[c.Type]));
                }
                ModelQuery = ModelQuery.Replace("ProjectName", ProjectName);
                ModelQuery = ModelQuery.Replace("TableName", TableName);
                ModelQuery = ModelQuery.Replace("QueryColumnName", sb.ToString());
                FileHelper.WriteFile(ModelQuery, path + TableName + "Query.cs");
                return "OK";
            }
            catch (Exception e)
            {
                return e.Message.ToString();
            }
        }
        #endregion

        #region 处理Ext
        public string BuildExt(IList<TColumn> list)
        {
            try
            {
                string path = ExtPath;
                NameValueCollection ps = new NameValueCollection();

                //Ext
                string AutoExpandColumn = string.Empty;
                string ColumnType = string.Empty;


                StringBuilder sbRecordField = new StringBuilder();
                StringBuilder sbGridField = new StringBuilder();
                StringBuilder sbEditField = new StringBuilder();

                //ExtCS
                StringBuilder sbInitInfo = new StringBuilder();
                StringBuilder sbSetInfo = new StringBuilder();
                StringBuilder sbSaveInfo = new StringBuilder();
                StringBuilder sbDesignerField = new StringBuilder();


                if (list.Count == 0) return "OK";

                ps.Set("string", "Column");
                ps.Set("DateTime", "DateColumn  Format=\"Y-m-d\"");
                ps.Set("stringField", "TextField");
                ps.Set("DateTimeField", "DateField");
                ps.Set("DateTimeFormat", "Editable=\"false\" Disabled=\"True\" DateFormat=\"yyyy-MM-dd HH:mm:ss\"");
                ps.Set("TextArea", "MaxLength=\"127\"");

                NameValueCollection psFieldType = new NameValueCollection();
                psFieldType.Set("Hot", "Checkbox");
                psFieldType.Set("Memo", "TextArea");

                foreach (TColumn c in list)
                {
                    //Store
                    AutoExpandColumn = c.NameEN;
                    sbRecordField.Append(string.Format(Cmds.strRecordField, c.NameEN));

                    if (c.NameEN == "Hot" || c.NameEN == "Scale") continue;
                    //建立ExtDesigner
                    sbDesignerField.Append(string.Format(Cmds.strDesignerField, c.NameEN, c.Field));
                    if (!string.IsNullOrEmpty(c.NameCN))
                    {
                        //Grid
                        sbGridField.Append(string.Format(Cmds.strGridField, c.NameEN, c.NameCN, string.IsNullOrEmpty(ps[c.Type]) ? "Column" : ps[c.Type]));
                        //Window
                        sbEditField.Append(string.Format(Cmds.strEditField, c.NameEN, c.NameCN, c.Field, ps[c.Field]));
                    }
                    
                    //建立ExtCS
                    if (c.Type != "string")
                    {
                        sbSetInfo.Append(string.Format(Cmds.strSetInfo.Replace(";", ".ToString();"), c.NameEN));
                        sbSaveInfo.Append(string.Format(Cmds.ExtCSSaveInfo[c.Type], c.NameEN));
                    }
                    else
                    {
                        sbSetInfo.Append(string.Format(Cmds.strSetInfo, c.NameEN));
                        sbSaveInfo.Append(string.Format(Cmds.strSaveInfo, c.NameEN));
                    }
                    sbInitInfo.Append(string.Format(Cmds.strInitInfo, c.NameEN));
                }

                ModelExt = ModelExt.Replace("ProjectName", ProjectName);
                ModelExt = ModelExt.Replace("TableName", TableName);
                ModelExt = ModelExt.Replace("ExtRecordField", sbRecordField.ToString());
                ModelExt = ModelExt.Replace("ExtGridField", sbGridField.ToString());
                ModelExt = ModelExt.Replace("ExtEditField", sbEditField.ToString());
                ModelExt = ModelExt.Replace("ExtAutoExpandColumn", AutoExpandColumn);

                ModelExtCS = ModelExtCS.Replace("ProjectName", ProjectName);
                ModelExtCS = ModelExtCS.Replace("TableName", TableName);
                ModelExtCS = ModelExtCS.Replace("ExtInitInfo", sbInitInfo.ToString());
                ModelExtCS = ModelExtCS.Replace("ExtSetInfo", sbSetInfo.ToString());
                ModelExtCS = ModelExtCS.Replace("ExtSaveInfo", sbSaveInfo.ToString());

                ModelExtDesigner = ModelExtDesigner.Replace("ProjectName", ProjectName);
                ModelExtDesigner = ModelExtDesigner.Replace("TableName", TableName);
                ModelExtDesigner = ModelExtDesigner.Replace("ExtDesignerField", sbDesignerField.ToString());

                ModelExtJS = ModelExtJS.Replace("TableName", TableName);

                FileHelper.WriteFile(ModelExt, path + "Default.aspx");
                FileHelper.WriteFile(ModelExtCS, path + "Default.aspx.cs");
                FileHelper.WriteFile(ModelExtJS, path + "Kwan." + TableName + ".js");
                FileHelper.WriteFile(ModelExtDesigner, path + "Default.aspx.designer.cs");
                return "OK";
            }
            catch (Exception e)
            {
                return e.Message.ToString();
            }
        }
        #endregion
    }
}
